package panda.server.data;

import java.io.Serializable;

import panda.client.enumerations.CardRarity;
import panda.client.enumerations.MagicSet;

/**
 * Contains information about a single Magic: the Gathering card. Immutable, except foil status.
 * @author zane.tian@gmail.com
 */
@SuppressWarnings("serial")
public class CardData implements Serializable, Comparable<CardData> {
	MagicSet set;
	String name;
	String castingCost;
	String type;
	String illustrator;
	CardRarity rarity;
	boolean foil = false;

	/* Magic cards are numbered per set. For example, Kird Ape is #199 of ninth edition. */
	int id;

	/* The card's body text in HTML. */
	String bodyText;

	public CardData() {
		/* empty for serialization requirements of GWT */
	}

	public CardData(MagicSet set, String name, String castingCost, String type, String bodyText, CardRarity rarity,
			String illustrator, int id) {
		
		/* makes sure this class never instantiates tokens - weird though, that this class knows about its subclass... */
		if(set.getAbbrev().contains("token") && !(this instanceof TokenData)) {
			throw new IllegalArgumentException("Cannot instantiate CardData with " + set.getAbbrev()
					+ ". Use TokenData constructor instead");
		}

		this.set = set;
		this.name = name;
		this.castingCost = castingCost;
		this.type = type;
		this.bodyText = bodyText;
		this.rarity = rarity;
		this.illustrator = illustrator;
		this.id = id;
	}
	
	public boolean isFoil() {
		return foil;
	}
	
	public void setFoil(boolean foil) {
		this.foil = foil;
	}

	public MagicSet getMagicSet() {
		return set;
	}

	public String getName() {
		return name;
	}

	public String getCastingCost() {
		/* the casting cost data from magiccards.info comes in this format: 3WW (5) */
		if(castingCost.equals("")) {
			return "0";
		} else {
			return castingCost.split(" ")[0];
		}
	}
	
	public String getConvertedCastingCost() {
		/* the casting cost data from magiccards.info comes in this format: 3WW (5) */
		if(castingCost.equals("") || castingCost.equals("0")) {
			return "0";
		} else {
			String genericWithParens = "boo!";
			try {
				genericWithParens = castingCost.split(" ")[1];
			} catch(Exception e) {
				System.out.println(name);
			}
			
			String result = "";
			result = genericWithParens.substring(1, genericWithParens.length() - 1);
			
			
			return result;
		}
	}

	public String getType() {
		return type;
	}

	public String getIllustrator() {
		return illustrator;
	}

	public CardRarity getRarity() {
		return rarity;
	}

	public String getBodyText() {
		return bodyText;
	}

	public int getID() {
		return id;
	}

	public String toString() {
		return isFoil()? name + " FOIL": name;
	}
	
	/* the equals method only checks for the card's name and set */
	public boolean equals(Object anObject) {
		if(this == anObject) {
			return true;
		}
		
		if(anObject instanceof CardData) {
			CardData casted = (CardData) anObject;
			return (casted.name == this.name) && (casted.set == this.set) && casted.id == this.id;
		}
		
		return false;
	}
	
	/* hashcode suggestion taken from Effective Java 2nd Ed. */
	public int hashCode() {
		int result = 17;
		result = 31 * result + name.hashCode();
		result = 31 * result + set.hashCode();

		return result;
	}
	
	public int compareTo(CardData o) {
		return this.name.compareTo(o.name);
	}
}